package com.sand.service.Impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sand.Exception.SandException;
import com.sand.dto.Owner.MerchantOrOwner;
import com.sand.dto.merchant.ContractAdd;
import com.sand.dto.merchant.ContractSelect;
import com.sand.entity.buy.scheme;
import com.sand.entity.conclude.content;
import com.sand.entity.conclude.contract;
import com.sand.entity.conclude.stage;
import com.sand.feign.OwnerFeign;
import com.sand.mapper.ContractMapper;
import com.sand.result.AppHttpCodeEnum;
import com.sand.service.ContentService;
import com.sand.service.ContractService;
import com.sand.service.StageService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.Objects;

@Service
public class ContractServiceImpl extends ServiceImpl<ContractMapper, contract> implements ContractService {

    @Autowired
    private OwnerFeign ownerFeign;

    @Autowired
    private ContentService contentService; //合同内容接口

    @Autowired
    private StageService stageService; // 合同预执行接口

    /**
     * 签订合同
     *
     * @param contractAdd
     */
    @Override
    @Transactional
    public Integer add(ContractAdd contractAdd) {

        //1.参数校验和默认初始化
        pan(contractAdd);

        //2.甲乙双方要和方案中的一样,同时该方案要是客户确定的,并且计算总金额
        panUser(contractAdd);

        //3.保存签订
        try {
            save(transition(contractAdd));
        } catch (Exception e) {
            throw new SandException(AppHttpCodeEnum.PARAM_INVALID,"保存的合同签订失败");
        }

        //4.查询刚刚保存的签订
        contract one = getOne(new LambdaQueryWrapper<contract>().eq(contract::getSchemeid, contractAdd.getSchemeid()));

        if (one == null){
            throw new SandException(AppHttpCodeEnum.PARAM_INVALID,"保存的合同签订失败");
        }

        //5.合同中的内容存入内容表,合同表保存id
        content content1 = new content();
        //5.1设置合同id
        content1.setContractid(one.getId());
        //5.2设置内容
        content1.setText(contractAdd.getText());
        //5.3添加合同内容表
        contentService.save(content1);

        //6.获取刚刚添加的合同内容表
        content cc = contentService.getOne(new LambdaQueryWrapper<content>().eq(content::getContractid, one.getId()));

        if (cc == null){
            throw new SandException(AppHttpCodeEnum.PARAM_INVALID,"保存合同内容时失败");
        }

        //7.给刚刚添加的合同设置合同内容表id
        one.setTextid(cc.getId());

        //8.修改刚刚添加的数据
        updateById(one);

        //9.添加合同预执行
        stage stage = new stage();

        stage.setOwnerid(contractAdd.getOwnerid());
        stage.setMerchantid(contractAdd.getMerchantid());
        stage.setContractid(one.getId());
        stage.setMeet(contractAdd.getBegintime());

        //添加
        stageService.add(stage);


        return 1;
    }

    /**
     * 查看商家或客户的一个所有合同
     *
     * @param merchantOrOwner
     */
    @Override
    public List<contract> Getlist(MerchantOrOwner merchantOrOwner) {
        Integer merchantid = merchantOrOwner.getMerchantid();

        Integer ownerid = merchantOrOwner.getOwnerid();

        LambdaQueryWrapper<contract> wrapper = new LambdaQueryWrapper<>();

        //都不传
        if (merchantid == null && ownerid == null) {
            throw new SandException(AppHttpCodeEnum.PARAM_INVALID, "未传入要查询的用户id");
        }

        //都传入
        if (merchantid != null && ownerid != null) {
            throw new SandException(AppHttpCodeEnum.PARAM_INVALID, "不能同时查询多个数据");
        }

        //查商家
        if (merchantid != null){
            wrapper.eq(contract::getMerchantid,merchantid);
            return list(wrapper);
        }

        //查客户
        wrapper.eq(contract::getOwnerid , ownerid);

        return list(wrapper);
    }

    /**
     * 查看合同详细信息
     *
     * @param contractid
     */
    @Override
    public ContractSelect getall(Integer contractid) {

        //判断id
        if (contractid == null){
            throw new SandException(AppHttpCodeEnum.PARAM_INVALID,"没有传入搜素的合同id");
        }

        //查询合同
        contract one = getById(contractid);

        if (one == null){
            throw new SandException(AppHttpCodeEnum.PARAM_INVALID,"该id不存在");
        }

        //查询合同内容
        content tow = contentService.getById(one.getTextid());

        //拼接
        ContractSelect contractSelect = new ContractSelect();

        BeanUtils.copyProperties(one,contractSelect);

        contractSelect.setText(tow.getText());

        //返回
        return contractSelect;
    }

    /**
     * 查看合同
     *
     * @param id
     */
    @Override
    public contract get(Integer id) {

        if (id == null){
            throw new SandException(AppHttpCodeEnum.PARAM_INVALID,"没有传入查询的合同id");
        }

        return getById(id);
    }

    /**
     * 完成合同
     *
     * @param contractid
     */
    @Override
    public Integer ok(Integer contractid) {

        //判断合同是否存在
        contract contract = getById(contractid);

        if (contract == null){
            throw new SandException(AppHttpCodeEnum.PARAM_INVALID,"合同不存在");
        }

        //修改
        contract.setBellon(1);

        updateById(contract);

        return 1;
    }


    /**
     * 新增合同的参数校验
     * @param contractAdd
     */
    public  void pan(ContractAdd contractAdd){

        if (contractAdd.getMerchantid() == null){
            throw new SandException(AppHttpCodeEnum.PARAM_INVALID,"没有传入甲方");
        }

        if (contractAdd.getOwnerid() == null){
            throw new SandException(AppHttpCodeEnum.PARAM_INVALID,"没有传入乙方");
        }

        if (contractAdd.getSchemeid() == null){
            throw new SandException(AppHttpCodeEnum.PARAM_INVALID,"没有传入方案");
        }

        if (contractAdd.getSubscription() == null){
            throw new SandException(AppHttpCodeEnum.PARAM_INVALID,"没有传入订金");
        }

        if (contractAdd.getText() == null){
            throw new SandException(AppHttpCodeEnum.PARAM_INVALID,"没有传入合同内容");
        }

        if (contractAdd.getBegintime() == null){
            throw new SandException(AppHttpCodeEnum.PARAM_INVALID,"没有传入合同开始时间");
        }

        if (contractAdd.getOvertime() == null){
            throw new SandException(AppHttpCodeEnum.PARAM_INVALID,"没有传入预计结束时间");
        }

        

        //默认参数设置

        //设置默认合同未完成
        contractAdd.setBellon(0);

        //合同创建时间为合同签订时间
        contractAdd.setBegintime(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));

    }

    /**
     * 合同中的甲乙双方校验
     */
    public  void panUser(ContractAdd contractAdd) {

        //根据id获取客户确认了的方案
        scheme scheme = ownerFeign.getid(contractAdd.getSchemeid()).getData();

        if (scheme == null){
            throw new SandException(AppHttpCodeEnum.PARAM_INVALID,"没有找到方案");
        }

        if (scheme.getRightt() == 0){
            throw new SandException(AppHttpCodeEnum.PARAM_INVALID,"该方案客户为确定");
        }

        //获取方案中甲乙方
        Integer merchantid = scheme.getMerchantid();
        Integer ownerid = scheme.getOwnerid();

        //比对签订合同的甲乙方
        if (!Objects.equals(merchantid, contractAdd.getMerchantid())){
            throw new SandException(AppHttpCodeEnum.PARAM_INVALID,"签订合同的乙方与方案中的乙方不一样");
        }

        if (!Objects.equals(ownerid, contractAdd.getOwnerid())){
            throw new SandException(AppHttpCodeEnum.PARAM_INVALID,"签订合同的乙方与方案中的甲方不一样");
        }

        //总金额由双方约定,如果没有约定默认是方案的总金额+设计费用
        if (contractAdd.getMoney() == null){
            contractAdd.setMoney(scheme.getMoney() + scheme.getDesignmoney());
        }

    }

    /**
     * 用于添加合同的实体与合同实体的转换
     * @param contractAdd
     * @return
     */
    private contract transition(ContractAdd contractAdd) {
        contract contract = new contract();

        BeanUtils.copyProperties(contractAdd,contract);

        contract.setTextid(null);

        return contract;
    }

}
